package ArrayBasedQueue;


import interfaces.Queue;

import java.util.Collection;
import java.util.Iterator;
import java.util.NoSuchElementException;

public class ArrayBasedQueue<E> implements Queue<E> {

    protected final int DEFAULT_CAPACITY = 16;
    private E[] elements;
    private int front;
    private int back;
    private int capacity;
    private int numberOfElementsInArray;

    public ArrayBasedQueue(int size) {
        capacity = size;
        back = size - 1;
        elements = (E[]) new Object[size];
    }

    public ArrayBasedQueue() {
        capacity = DEFAULT_CAPACITY;
        back = DEFAULT_CAPACITY - 1;
        elements = (E[]) (new Object[DEFAULT_CAPACITY]);
    }


    public boolean isEmpty() {
        return numberOfElementsInArray == 0;
    }

    @Override
    public E element() {

        if (isEmpty()) {
            throw new NoSuchElementException("Queue is empty");
        } else

            return elements[front];
    }

    private boolean full() {
        return (numberOfElementsInArray == capacity);
    }

      @Override
    public boolean offer(E e) {

        if (!this.full()) {
            back = (back + 1) % capacity;
            elements[back] = e;
            numberOfElementsInArray++;
            return true;
        }

        return false;
    }

    public void ExpandQueue(int newSize) {
        E[] tmp = (E[]) new Object[newSize];
        int current = front;
        for (int i = 0; i < numberOfElementsInArray; i++) {
            tmp[i] = elements[current];
            current = (current + 1) % numberOfElementsInArray;
        }
        elements = tmp;
        front = 0;
        back = numberOfElementsInArray - 1;
        capacity = newSize;

    }

    @Override
    public E peek() {

        if (!isEmpty())
            return elements[front];

        return null;
    }

    @Override
    public E poll() {
        E element = null;
        if (!isEmpty()) {
            element = elements[front];
            front = (front + 1) % capacity;
            numberOfElementsInArray--;
        }
        return element;
    }

    @Override
    public E remove() {
        E element;
        if (!isEmpty()) {
            element = elements[front];
            front = (front + 1) % capacity;
            numberOfElementsInArray--;

        } else {
            throw new NoSuchElementException(" Queue is empty");
        }
        return element;
    }

}
